<!-- src/components/ThreeScene.vue -->
<template>
  <div ref="container" class="scene-container"></div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from "vue";
import * as THREE from "three";
import textureImage from "../assets/473ee8a12b93506ecb0ae4f17ce9a188.png";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
// 导入GSAP
import gsap from "gsap";
//导入dat.gui
import * as dat from "dat.gui";
//给当前组件一个名称，使用defineOptions定义
defineOptions({
  name: "ThreeScene",
});

const container = ref<HTMLElement>();
let scene: THREE.Scene;
let camera: THREE.PerspectiveCamera;
let renderer: THREE.WebGLRenderer;
let cube: THREE.Mesh;
//声明轨道控制器
let controls: OrbitControls;

// 初始化场景
const initScene = () => {
  const loadingDiv = document.createElement("div");
  loadingDiv.style.position = "fixed";
  loadingDiv.style.top = "50%";
  loadingDiv.style.left = "50%";
  loadingDiv.style.transform = "translate(-50%, -50%)";
  document.body.appendChild(loadingDiv);
  //创建场景
  scene = new THREE.Scene();
  //创建相机
  camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    0.1,
    100
  );
  //创建渲染器
  renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);
  container.value?.appendChild(renderer.domElement);
  controls = new OrbitControls(camera, renderer.domElement);
  controls.enableDamping = true;
  controls.dampingFactor = 0.05;
  //创建坐标轴
  const axesHelper = new THREE.AxesHelper(5);
  scene.add(axesHelper);
  camera.position.set(0, 0, 10);
  scene.add(camera);
  // 定义事件处理器接口
  interface LoadingEvents {
    onLoad: (event?: any) => void;
    onProgress: (url: string, loaded: number, total: number) => void;
    onError: (url: string) => void;
  }
  //设置加载管理器
  const event: LoadingEvents = {
    onLoad: (event) => {
      console.log("纹理图加载完成", event);
      loadingDiv.style.display = "none";
    },
    onProgress: (url, loaded, total) => {
      console.log("纹理图加载中", {
        url,
        loaded,
        total,
        progress: `${((loaded / total) * 100).toFixed(2)}%`,
      });
      loadingDiv.textContent = `加载进度：${Math.floor(
        (loaded / total) * 100
      )}%`;
    },
    onError: (url) => {
      console.log("纹理图加载失败", url);
    },
  };

  const loadingManager = new THREE.LoadingManager(
    event.onLoad,
    event.onProgress,
    event.onError
  );
  //导入纹理
  const textureLoader = new THREE.TextureLoader(loadingManager);
  //导入颜色贴图
  const doorColorTexture = textureLoader.load("/color.png");
  // const loader = new THREE.TextureLoader();
  //单张纹理图的加载
  // const doorColorTexture = loader.load(
  //   "/color.png",
  //   //onLoad
  //   () => {
  //     console.log("纹理图加载完成");
  //   },
  //   //onProgress
  //   (event) => {
  //     console.log("纹理图加载中", event);
  //   },
  //   //onError
  //   (err) => {
  //     console.log("纹理图加载失败", err);
  //   }
  // );
  //导入透明度贴图
  const alphaMapTexture = textureLoader.load("/alpha.png");
  //导入ao贴图
  const aoMapTexture = textureLoader.load("/ambientOcclusion.png");
  //导入置换贴图
  const displacementMapTexture = textureLoader.load("/displacement.jpeg");
  //导入粗糙度贴图
  const roughnessMapTexture = textureLoader.load("/roughness.jpeg");
  // 导入金属贴图
  const metalnessMapTexture = textureLoader.load("/metalness.jpeg");
  //导入法线贴图
  const normalMapTexture = textureLoader.load("/normal.jpeg");
  //添加物体
  const cubeGeometry = new THREE.BoxGeometry(1, 1, 1, 100, 100, 100); //物体
  //材质
  const material = new THREE.MeshStandardMaterial({
    color: "#ffff00",
    map: doorColorTexture,
    alphaMap: alphaMapTexture,
    aoMap: aoMapTexture,
    displacementMap: displacementMapTexture,
    displacementScale: 0.1,
    roughness: 1,
    roughnessMap: roughnessMapTexture,
    transparent: true,
    side: THREE.DoubleSide,
    metalness: 1,
    metalnessMap: metalnessMapTexture,
    normalMap: normalMapTexture,
  });

  // 添加第二组UV坐标
  cubeGeometry.setAttribute(
    "uv2",
    new THREE.BufferAttribute(cubeGeometry.attributes.uv.array, 2)
  );
  //添加平面
  const planeGeometry = new THREE.PlaneGeometry(1, 1, 200, 200);
  const plane = new THREE.Mesh(planeGeometry, material);
  plane.position.set(2, 0, 0);
  scene.add(plane);
  //给平面设置第二组uv
  planeGeometry.setAttribute(
    "uv2",
    new THREE.BufferAttribute(planeGeometry.attributes.uv.array, 2)
  );
  //灯光--环境光
  const light = new THREE.AmbientLight(0xffffff, 0.5);
  scene.add(light);
  // //灯光--平行光
  const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
  directionalLight.position.set(10, 10, 10);
  scene.add(directionalLight);
  cube = new THREE.Mesh(cubeGeometry, material);

  scene.add(cube);

  // 添加轨道控制器
  controls = new OrbitControls(camera, renderer.domElement);

  // 调用动画循环
  animate();
};
onMounted(() => {
  initScene();
});
// 添加动画循环函数
const animate = () => {
  requestAnimationFrame(animate);
  // 更新控制器
  controls.update();
  // 渲染场景
  renderer.render(scene, camera);
};
</script>

<style scoped lang="less">
.scene-container {
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  background: #000;
}
</style>
